import sys
import os
import math
from PySide6.QtWidgets import (QLineEdit, QPushButton, QApplication,
                               QVBoxLayout, QDialog, QLabel, QDial)
import pyecharts.options as opts
from pyecharts.charts import Line
from pyecharts.options import series_options


class Form(QDialog):

    def __init__(self, parent=None):
        super(Form, self).__init__(parent)
        self.count = 0
        self.graph_data = []
        self.title_text = "螺线管轴线上的磁场强度分布"
        self.debug = False
        if(self.debug):
            self.graph_data = [[x*0.1, 1] for x in range(-30, 100)]
        # Create widgets
        self.title = QLabel(
            "<font color=red size=40> " + self.title_text + "</font>")
        self.K_label = QLabel("K值（k=R/d，其中R为霍尔系数，d为霍尔元件厚度）")
        self.K_edit = QLineEdit()
        self.L_label = QLabel("螺线管的长度（厘米）")
        self.L_edit = QLineEdit()
        self.D_label = QLabel("螺线管的直径（厘米）")
        self.D_edit = QLineEdit()
        self.N_label = QLabel("螺线管的匝数")
        self.N_edit = QLineEdit()
        self.Ih_label = QLabel("霍尔工作电流Ih（毫安）")
        self.Ih_edit = QLineEdit()
        self.Uh_pp_label = QLabel("霍尔电压正正（毫伏）")
        self.Uh_pp_edit = QLineEdit()
        self.Uh_pn_label = QLabel("霍尔电压正反（毫伏）")
        self.Uh_pn_edit = QLineEdit()
        self.Uh_nn_label = QLabel("霍尔电压反反（毫伏）")
        self.Uh_nn_edit = QLineEdit()
        self.Uh_np_label = QLabel("霍尔电压反正（毫伏）")
        self.Uh_np_edit = QLineEdit()
        self.X1_label = QLabel("X1（厘米）（X= 14cm - X1 -X2）")
        self.X1_edit = QLineEdit()
        self.X2_label = QLabel("X2（厘米）")
        self.X2_edit = QLineEdit()
        self.counter = QLabel("<font color=red>已经输入 0 组数据</font>")
        self.ad = QLabel(
            r'由盖圳彪编写，欢迎访问<a href="https://www.gzblog.tech">我的博客</a>')
        self.ad.setOpenExternalLinks(True)
        self.add_measure = QPushButton("添加数据")
        self.generate_graph = QPushButton("生成图表")
        # Create layout and add widgets
        layout = QVBoxLayout()
        layout.addWidget(self.title)
        layout.addWidget(self.K_label)
        layout.addWidget(self.K_edit)
        layout.addWidget(self.L_label)
        layout.addWidget(self.L_edit)
        layout.addWidget(self.D_label)
        layout.addWidget(self.D_edit)
        layout.addWidget(self.N_label)
        layout.addWidget(self.N_edit)
        layout.addWidget(self.Ih_label)
        layout.addWidget(self.Ih_edit)
        layout.addWidget(self.Uh_pp_label)
        layout.addWidget(self.Uh_pp_edit)
        layout.addWidget(self.Uh_pn_label)
        layout.addWidget(self.Uh_pn_edit)
        layout.addWidget(self.Uh_nn_label)
        layout.addWidget(self.Uh_nn_edit)
        layout.addWidget(self.Uh_np_label)
        layout.addWidget(self.Uh_np_edit)
        layout.addWidget(self.X1_label)
        layout.addWidget(self.X1_edit)
        layout.addWidget((self.X2_label))
        layout.addWidget(self.X2_edit)
        layout.addWidget(self.counter)
        layout.addWidget(self.ad)
        layout.addWidget(self.add_measure)
        layout.addWidget(self.generate_graph)

        self.setLayout(layout)
        self.add_measure.clicked.connect(self.handle_add_measure)
        self.generate_graph.clicked.connect(self.handle_generate_graph)

    # 取得数据
    def get_measures(self):
        results = {}
        results['K'] = float(self.K_edit.text())  # 注意K是大写
        results['Ih'] = float(self.Ih_edit.text())
        Uhs = []
        Uhs.append(float(self.Uh_pp_edit.text()))
        Uhs.append(float(self.Uh_pn_edit.text()))
        Uhs.append(float(self.Uh_nn_edit.text()))
        Uhs.append(float(self.Uh_np_edit.text()))
        Uhs = [abs(x) for x in Uhs]
        results['Uh'] = sum(Uhs)/len(Uhs)
        results['X'] = 14 - (float(self.X1_edit.text()) +
                             float(self.X2_edit.text()))
        return results

    def calculate_B(Uh, K, Ih):
        return Uh/K*Ih
    # 计算结果

    def get_B(self):
        measures = self.get_measures()
        # mT
        return [measures['X'], 1000 * measures['Uh']/(measures['K'] * measures['Ih'])]

    def handle_add_measure(self):
        try:
            self.graph_data.append(self.get_B())
            begin_alert = "<font color=red>已经输入 "
            end_alert = " 组数据</font>"
            self.count += 1
            self.counter.setText(begin_alert + str(self.count) + end_alert)
        except:
            pass

    def handle_generate_graph(self):
        saved_path = os.getcwd() + "\\" + self.title_text + "图" + ".html"

        def calculate_theoretical_value(x):
            miu = 4 * math.pi * 1e-7
            x = x * 0.1
            if self.debug:
                L = 0.1502
                I = 0.5
                D = 0.0189
                N = 1535
            else:
                I = float(self.Ih_edit.text()) * 1e-3
                D = float(self.D_edit.text()) * 0.1
                N = int(self.N_edit.text())
                L = float(self.L_edit.text()) * 0.1
            R = D/2
            return (miu * N * I / (2 * L)) * ((x+L)/math.sqrt(R**2 + (x+L) ** 2) - (x-L)/math.sqrt(R**2 + (x-L) ** 2))

        try:
            theoretical_values = [
                1000*x for x in map(calculate_theoretical_value, [item[0] for item in self.graph_data])]
        except:
            return
        (
            Line(init_opts=opts.InitOpts(width="1400px", height="700px"))
            .add_xaxis(xaxis_data=[item[0] for item in self.graph_data])
            .add_yaxis(
                series_name="磁场强度(mT)",
                y_axis=[item[1] for item in self.graph_data],
                yaxis_index=0,
                is_smooth=True,
                is_symbol_show=False,
            )
            .add_yaxis(
                series_name="理论磁场强度（mT）",
                y_axis=theoretical_values,
                is_smooth=True,
                is_symbol_show=True
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(title=self.title_text),
                tooltip_opts=opts.TooltipOpts(trigger="axis"),
                datazoom_opts=[
                    opts.DataZoomOpts(yaxis_index=0),
                    opts.DataZoomOpts(type_="inside", yaxis_index=0),
                ],
                xaxis_opts=opts.AxisOpts(
                    type_="value", name="位置（cm）", name_location='end'),
                yaxis_opts=opts.AxisOpts(
                    type_="value",
                    name_location="end",
                    min_=0,
                    is_scale=True,
                    axistick_opts=opts.AxisTickOpts(is_inside=False),
                    name="磁场强度（mT）"
                ),
            )
            .render(saved_path)
        )
        self.counter.setText("图表已经保存到：" + saved_path)
        return


if __name__ == '__main__':
    app = QApplication(sys.argv)
    form = Form()
    form.setWindowTitle(form.title_text)
    form.show()
    sys.exit(app.exec())
